home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 6 / FM Towns Free Software Collection 6.iso / ms_dos / compack / src / compack.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-08  |  7.6 KB  |  293 lines

  1. /*    :
  2.     :        「compack.c」  ~ command pack utility ~
  3.     :                                                    by  Shinki.
  4.     :                    1991.11.09            1st version
  5.     :            ※ char = unsigned char
  6. */
  7.  
  8. #include    <string.h>
  9. #include    <stdio.h>
  10. #include    <stdlib.h>
  11. #include    <memory.h>
  12. #include    <ctype.h>
  13.  
  14. #define        LIST        0
  15. #define        DELETE        1
  16. #define        ADD            2
  17. #define        RENAME        3
  18.  
  19. /*
  20. #define        debug
  21. */
  22. #define        LEN            602
  23. #define        MAX_LEN        0x5fff        /*  最大ベースファイル長  */
  24.  
  25. extern    char    basefile[LEN];
  26.  
  27.         char    base_id[]=
  28.                      {  0xeb,0x35,0x43,0x4f,0x4d,0x50,0x41,0x43,0x4b };
  29.  
  30. void    main( int argc,char *argv[] );
  31. void    help( void );
  32. void    job( char *file1,char *file2,int mode );
  33. size_t    GetFileLength( char *name );
  34. void    error( char *msg1,char *msg2 );
  35.  
  36. void    main( int argc,char *argv[] )
  37. {    char    *s;
  38.     int                mode;
  39.     char    file1[128],file2[128];
  40.     int                i,n;
  41.  
  42. /*  変数初期化  */
  43.     mode=ADD;
  44.     strcpy( file1,"" );
  45.     strcpy( file2,"" );
  46.  
  47.     for( i=1;i<argc;i++ )
  48.     {    s=argv[i];
  49.         if( *s=='-' || *s=='/' || *s=='^' )
  50.         {    switch( *(++s) )
  51.             {
  52. /*                case 'd':    case 'D':
  53.                     mode=DELETE;
  54.                     break;
  55. */                case 'L':    case 'l':
  56.                     mode=LIST;
  57.                     break;
  58.                 case 'A':    case 'a':
  59.                     mode=ADD;
  60.                     break;
  61.                 case 'H':    case 'h':    case '?':        /*  help  */
  62.                     help();        /*  and exit  */
  63.                 default:
  64.                     printf( "@ オプション指定エラー!!  ('%c')\n\n",*s );
  65.                     exit( 1 );
  66.             }
  67.         }
  68.     }
  69.  
  70.     n=0;
  71.     for( i=1;i<argc;i++ )
  72.     {    s=argv[i];
  73.         if( *s=='-' || *s=='/' || *s=='^' )
  74.             continue;
  75.  
  76.         if( (n++)==0 )
  77.         {    strcpy( file1,s );
  78.             if( (s=strrchr( file1,'.' ))!=NULL )
  79.                 *s='\0';
  80.             strcat( file1,".com" );
  81.         }
  82.         else
  83.         {    strcpy( file2,s );
  84.             if( (s=strrchr( file2,'.' ))!=NULL )
  85.                 *s='\0';
  86.             strcat( file2,".com" );
  87.             if( mode!=LIST )
  88.                 job( file1,file2,mode );    /*  add/delete モード時  */
  89.         }
  90.     }
  91.     if( file1[0]!='\0' && file2[0]=='\0' )
  92.         mode=LIST;                /*  ベースファイルのみ指定時は、LIST指定に  */
  93.     if( file1[0]=='\0' )
  94.         help();                    /*  ベースファイル指定無き場合は、HELP & EXIT  */
  95.     if( mode==LIST )
  96.         job( file1,"",mode );    /*  LIST モード時  */
  97. }
  98.  
  99. size_t    GetFileLength( char *name )        /*  ==0.....errror  */
  100. {    FILE    *fd;
  101.     size_t    len;
  102.  
  103.     if ( (fd=fopen( name,"rb" ))==NULL )
  104.         return( 0 );
  105.     fseek( fd,0,SEEK_END );
  106.     len=(size_t)ftell( fd );
  107.     if ( fclose( fd )==EOF )
  108.         error( "file close","get_file_length" );
  109.     return( len );
  110. }
  111.  
  112. void    error( char *msg1,char *msg2 )
  113. {    printf( "@System error : '%s'   in function:「%s」\n",msg1,msg2 );
  114.     printf( "program aborted!!\n\n" );
  115.     exit( 2 );
  116. }
  117.  
  118. void    help( void )
  119. {    printf( "☆☆☆ Help Message for ComPack v1.00  By Shinki.  ☆☆☆\n"
  120.             "\n    ComPack : 小さいCOMファイルをひとまとめにする\n"
  121.             "    書式    : ComPack [-/Option] ベースファイル [ターゲットファイル1"
  122.                                                         " [ターゲット2 ・・・・]]\n" );
  123.     printf( "    Option  : '?' or 'H' .... ヘルプメッセージ表示(この画面)\n"
  124.             "            : 'a'        .... ベースファイルにターゲットファイルを"
  125.                                                             "しまい込む\n" );
  126.     printf( "            : 'l'        .... ベースファイルの中身を調べる\n" );
  127. /*
  128.             "            : 'd'        .... ベースファイルからターゲットファイル"
  129.                                                             "を削除する\n\n" );
  130. */
  131.     printf( "    Ex.     : compack all prog1  ... all.com に prog1 を追加\n" );
  132.     printf( "            : compack all        ... all.com の中身を閲覧\n\n" );
  133.     exit( 0 );
  134. }
  135.  
  136. void    job( char *file1,char *file2,int mode )
  137. {    FILE            *fp1;
  138.     size_t            len1,len2;
  139.     char    buff[MAX_LEN];
  140.     char    temp[128];                    /*  追加モジュール名認知用  */
  141.     unsigned int    pointer;
  142.     char    *s;
  143.     char    c;
  144.     unsigned int    address;
  145.     unsigned int    write_size;                    /*  書き込みサイズ  */
  146.     int                nn,n;                        /*  連結プログラム数  */
  147.     int                i;                            /*  ループカウンタ  */
  148.  
  149.     len1=GetFileLength( file1 );
  150.  
  151.     if( len1>MAX_LEN )                            /*  大きすぎた場合  */
  152.     {    printf( "@ これ以上プログラムを追加できません\n" );
  153.         goto    end;
  154.     }
  155.     if( len1==0 )
  156.     {    memcpy( buff,basefile,LEN );            /*  新規作成時  */
  157.         len1=LEN;
  158.     }
  159.     else
  160.     {    if( (fp1=fopen( file1,"rb" ))==NULL )
  161.             error( "file open","job" );
  162.         if( fread( buff,1,(size_t)len1,fp1 )<len1 )
  163.             error( "file read","job" );
  164.         if( fclose( fp1 )==EOF )
  165.             error( "file close","job" );
  166.         for( i=0;i<8;i++ )                /*  ベースファイルのIDチェック  */
  167.         {    if( base_id[i]!=buff[i] )
  168.             {    printf( "@ ベースファイルが異常です\n" );
  169.                 exit( 1 );
  170.             }
  171.         }
  172.     }
  173.  
  174.     pointer=(buff[10]-1)*256+buff[9];        /*  header位置へリストア  */
  175.     nn=n=buff[pointer];
  176.  
  177. #ifdef    debug
  178.     printf( "ヘッダ位置.......0x%04X\n",pointer );
  179.     printf( "連結プログラム数......%d\n",n );
  180.     printf( "buff[ 9].......%d\n",buff[9] );
  181.     printf( "buff[10].......%d\n",buff[10] );
  182. #endif
  183.  
  184.     switch( mode )
  185.     {    case    ADD:
  186.             printf( "「%s」に「%s」を追加します\n",file1,file2 );
  187.             if( (len2=GetFileLength( file2 ))==0 )
  188.             {    printf( "\x07        \x1b[31mファイルが見つかりません\x1b[m\n"
  189.                                                                     ,file2 );
  190.                 goto    end;
  191.             }
  192.  
  193.  
  194. #ifdef    debug
  195.     printf( "length1.....%d  /  length2.....%d\n",len1,len2 );
  196. #endif
  197.  
  198.             if( (write_size=len1+len2+0x10)>=MAX_LEN )
  199.             {    printf( "\x07        \x1b[31mこれ以上追加できません\x1b[m\n" );
  200.                 goto    end;
  201.             }
  202.  
  203.             buff[pointer++]++;                /*  連結プログラム数 インクリメント  */
  204.  
  205.             while( (n--)>0 )
  206.             {    address=buff[pointer+10]+buff[pointer+11]*256+0x10;
  207.                 buff[pointer+10]=address%256;
  208.                 buff[pointer+11]=address/256;    /*  格納位置をヘッダ分プラス  */
  209.                 pointer+=0x10;                    /*  ヘッダのスキップ  */
  210.             }
  211.  
  212. #ifdef    debug
  213.     printf( "(len1-pointer)=%d\n",len1-pointer );
  214. #endif
  215.  
  216.             if( nn!=0 )
  217.                 memmove( &buff[pointer+0x10],&buff[pointer],
  218.                                                 (size_t)(len1-pointer) );
  219.  
  220.             strcpy( temp,file2 );
  221.             if( (s=strrchr( temp,'.' ))!=NULL )
  222.                 *s='\0';
  223.             if( (s=strrchr( temp,'\\' ))==NULL )
  224.                 s=temp;
  225.             if( *s=='\\' )
  226.                 s++;
  227.             if( *(s+1)==':' )
  228.                 s+=2;
  229.             sprintf( &buff[pointer],"%-8s",s );        /*  s:モジュール名  */
  230.             for( i=1;i<=8;i++ )
  231.             {    c=buff[pointer];                /*  モジュール名記入終了  */
  232.                 buff[pointer++]=toupper( c );    /*     (オオモジ カ )   */
  233.             }
  234. #ifdef    debug
  235.     printf( "write_size ......%d\n",write_size );
  236.     printf( "モジュール名 : '%-8s'\n",s );
  237. #endif
  238.  
  239.             buff[pointer++]=len2%256;
  240.             buff[pointer++]=len2/256;            /*  モジュールサイズ記入  */
  241.  
  242.             address=len1+0x110;                /*  address:追記プログラム格納位置  */
  243.             buff[pointer++]=address%256;
  244.             buff[pointer++]=address/256;        /*  格納位置の記入終了  */
  245.  
  246.             buff[pointer++]=buff[pointer++]=buff[pointer++]=buff[pointer]=0;
  247.                                                 /*  予約領域をゼロクリア  */
  248.  
  249.             pointer=len1+0x10;                    /*  追加位置へ移動  */
  250.  
  251.  
  252.  
  253.             if( (fp1=fopen( file2,"rb" ))==NULL )
  254.                 printf( "file open(file2)","job" );
  255.             if( fread( &buff[pointer],1,(size_t)len2,fp1 )<len2 )
  256.                 error( "file read","job" );
  257.             if( fclose( fp1 )==EOF )
  258.                 error( "file close(file2)","job" );
  259.                                                 /*  追加モジュール読み込み終了  */
  260.  
  261.             if( (fp1=fopen( file1,"wb" ))==NULL )
  262.                 error( "file open(basefile-write)","job" );
  263.  
  264.             if( fwrite( buff,1,write_size,fp1 )<write_size )
  265.                 error( "file write(basefile-write)","job" );
  266.             if( fclose( fp1 )==EOF )
  267.                 error( "file close(basefile-write)","job" );
  268.             break;
  269.         case    LIST:
  270.             printf( "ベースファイル 「%s」 の一覧\n\n",file1 );
  271.             if( n==0 )
  272.             {    printf( "@ ベースファイルが見つかりません\n" );
  273.                 exit( 1 );
  274.             }
  275.             pointer++;
  276.             printf( "  コマンド名        サイズ\n"
  277.                     "---------------   -----------\n"
  278.                     "ComPack本体         $%04x\n",pointer );
  279.             for( ;n>0;n-- )
  280.             {    for( i=1;i<=8;i++ )
  281.                     putchar( buff[pointer++] );
  282.                 len2=buff[pointer++]+buff[pointer]*256;
  283.                 printf( "              $%04x\n",len2 );
  284.                 pointer+=7;            /*  予約領域スキップ  */
  285.             }
  286.             printf( "---------------   -----------\n"
  287.                     "    合計              $%04x  (残り $%04x バイト)\n"
  288.                                                 ,len1,MAX_LEN-len1 );
  289.             break;
  290.     }
  291. end:;
  292. }
  293.